﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace CloudStorageLight.Core
{
    public class GoogleDriveUtilProxy
    {
        static Type googleDriveUtilClass;
        static PropertyInfo GoogleDriveClientIdProp;
        static PropertyInfo GoogleDriveClientSecretProp;
        static MethodInfo AuthorizeAsyncMethod;

        static GoogleDriveUtilProxy()
        {
            googleDriveUtilClass = Type.GetType("CloudStorageLight.Core.GoogleDriveUtil, CloudStorageLight.Extension");
            if (googleDriveUtilClass != null)
            {
                GoogleDriveClientIdProp = googleDriveUtilClass.GetProperty("GoogleDriveClientId");
                GoogleDriveClientSecretProp = googleDriveUtilClass.GetProperty("GoogleDriveClientSecret");
                AuthorizeAsyncMethod = googleDriveUtilClass.GetMethod("AuthorizeAsync");
            }
        }

        public static string GoogleDriveClientId
        {
            get 
            {
                if (GoogleDriveClientIdProp == null) return null;
                return (string)GoogleDriveClientIdProp.GetValue(null); 
            }
            set 
            {
                if (GoogleDriveClientIdProp == null) return;
                GoogleDriveClientIdProp.SetValue(null, value); 
            }
        }


        public static string GoogleDriveClientSecret
        {
            get 
            {
                if (GoogleDriveClientSecretProp == null) return null;
                return (string)GoogleDriveClientSecretProp.GetValue(null); 
            }
            set 
            {
                if (GoogleDriveClientSecretProp == null) return;
                GoogleDriveClientSecretProp.SetValue(null, value); 
            }
        }

        public static Task<Dictionary<string, object>> AuthorizeAsync(string path, string callbackUrl, string returnUrl, HttpContextBase ctx)
        {
            if (AuthorizeAsyncMethod == null) throw new NotSupportedException();
            return (Task<Dictionary<string, object>>)AuthorizeAsyncMethod.Invoke(null, new object[] { path, callbackUrl, returnUrl, ctx });
        }
    }

    public class GoogleDriveBlobAdapterProxy : IBlobAdapter
    {
        private BlobContainer _parent;
        private string _rootPath;

        static Type googleAdapterClass = Type.GetType("CloudStorageLight.Core.GoogleDriveBlobAdapter, CloudStorageLight.Extension");

        private IBlobAdapter googleAdapter;

        public GoogleDriveBlobAdapterProxy(string rootPath, string clientId, string clientSecret, string refreshToken, string filePath)
        {
            _rootPath = rootPath;
            if (googleAdapterClass != null)
            {
                googleAdapter = (IBlobAdapter)Activator.CreateInstance(googleAdapterClass, rootPath, clientId, clientSecret, refreshToken, filePath);
            }
        }


        public string RootPath
        {
            get 
            {
                if (googleAdapter == null) return _rootPath;
                return googleAdapter.RootPath; 
            }
        }

        public BlobContainer Parent
        {
            get
            {
                if (googleAdapterClass == null) return _parent;
                return googleAdapter.Parent;
            }
            set
            {
                if (googleAdapterClass != null) googleAdapter.Parent = value;
                _parent = value;
            }
        }

        public System.Threading.Tasks.Task CopyAsync(string path, BlobFile file)
        {
            if (googleAdapterClass == null) throw new InvalidOperationException("CloudStorageLight.Extension Required");
            return googleAdapter.CopyAsync(path, file);
        }

        public System.Threading.Tasks.Task<bool> DeleteAsync(BlobItem file)
        {
            if (googleAdapterClass == null) throw new InvalidOperationException("CloudStorageLight.Extension Required");
            return googleAdapter.DeleteAsync(file);
        }

        public System.Threading.Tasks.Task DownloadAsync(BlobItem item, System.IO.Stream stream)
        {
            if (googleAdapterClass == null) throw new InvalidOperationException("CloudStorageLight.Extension Required");
            return googleAdapter.DownloadAsync(item, stream);
        }

        public System.Threading.Tasks.Task DownloadAsync(BlobItem item, string localpath)
        {
            if (googleAdapterClass == null) throw new InvalidOperationException("CloudStorageLight.Extension Required");
            return googleAdapter.DownloadAsync(item, localpath);
        }

        public async System.Threading.Tasks.Task<bool> ExistsAsync(string path)
        {
            if (googleAdapterClass == null) return false;
            return await googleAdapter.ExistsAsync(path);
        }

        public System.Threading.Tasks.Task<List<BlobItem>> GetFilesAsync(string id, int maxSize, bool flat = false)
        {
            if (googleAdapterClass == null) throw new InvalidOperationException("CloudStorageLight.Extension Required");
            return googleAdapter.GetFilesAsync(id, maxSize, flat);
        }

        public System.Threading.Tasks.Task UploadAsync(BlobItem item, System.IO.Stream stream)
        {
            if (googleAdapterClass == null) throw new InvalidOperationException("CloudStorageLight.Extension Required");
            return googleAdapter.UploadAsync(item, stream);
        }

        public System.Threading.Tasks.Task UploadAsync(BlobItem item, string localpath)
        {
            if (googleAdapterClass == null) throw new InvalidOperationException("CloudStorageLight.Extension Required");
            return googleAdapter.UploadAsync(item, localpath);
        }

        public System.Threading.Tasks.Task GetMetadataAsync(BlobItem item)
        {
            if (googleAdapterClass == null) throw new InvalidOperationException("CloudStorageLight.Extension Required");
            return googleAdapter.GetMetadataAsync(item);
        }

        public System.Threading.Tasks.Task SetMetadataAsync(BlobItem item)
        {
            if (googleAdapterClass == null) throw new InvalidOperationException("CloudStorageLight.Extension Required");
            return googleAdapter.SetMetadataAsync(item);
        }

        public System.Threading.Tasks.Task CreateDirectoryAsync(BlobDirectory dire)
        {
            if (googleAdapterClass == null) throw new InvalidOperationException("CloudStorageLight.Extension Required");
            return googleAdapter.CreateDirectoryAsync(dire);
        }

        public void Dispose()
        {
            if (googleAdapter != null) googleAdapter.Dispose();
        }
    }

}
